import 'dart:collection';
import 'dart:io';

import 'package:base_app/commons/constants/app_constant.dart';
import 'package:base_app/utils/file_util.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:mime/mime.dart';

import 'in_app_web_js_bridge_register.dart';
import 'in_app_web_js_handler_manager.dart';

class WebViewInAppScreen extends StatefulWidget {
  const WebViewInAppScreen({
    super.key,
    required this.url,
    this.onWebProgress,
    this.onWebResourceError,
    this.onReceivedError,
    required this.onLoadFinished,
    required this.onWebTitleLoaded,
    this.onWebViewCreated,
  });

  final String url;
  final Function(int progress)? onWebProgress;
  final Function(String? errorMessage)? onWebResourceError;
  final Function(WebResourceError error)? onReceivedError;
  final Function(String? url) onLoadFinished;
  final Function(String? webTitle)? onWebTitleLoaded;
  final Function(InAppWebViewController controller)? onWebViewCreated;


  @override
  State<StatefulWidget> createState() => _WebViewInAppScreenState();

}

class _WebViewInAppScreenState extends State<WebViewInAppScreen> {

  final GlobalKey<_WebViewInAppScreenState> webViewKey = GlobalKey();

  InAppWebViewController? webViewController;

  InAppWebViewSettings settings = InAppWebViewSettings(
    javaScriptEnabled: true,
    allowFileAccessFromFileURLs: true,
    allowUniversalAccessFromFileURLs: true,
    useShouldOverrideUrlLoading: true,
    useOnLoadResource: true,
    transparentBackground: true,
    resourceCustomSchemes: [AppConstant.customerScheme],
  );

  // JS与Flutter调用的message Queue
  final InAppWebJSHandlerManager _inAppWebJSHandlerManager =
  InAppWebJSHandlerManager();

  // flutter注册供H5调用的方法
  late InAppWebJSBridgeRegister _inAppWebJSBridgeRegister;

  bool _isDisposed = false;

  double progress = 0.0;

  @override
  void initState() {
    super.initState();
    _isDisposed = false;

    _inAppWebJSBridgeRegister = InAppWebJSBridgeRegister(inAppWebJSHandlerManager: _inAppWebJSHandlerManager);
  }

  @override
  void dispose() async {
    if(!_isDisposed){
      if(context.mounted){
        _inAppWebJSHandlerManager.reset();
        await InAppWebViewController.clearAllCache(includeDiskFiles: true);
      }
    }
    _isDisposed = true;
    super.dispose();
  }

  // 设置页面标题
  void setWebPageTitle(data) {
    if (widget.onWebTitleLoaded != null) {
      widget.onWebTitleLoaded!(data);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Expanded(
            child: Stack(
              children: [
                InAppWebView(
                    key: webViewKey,
                    initialUrlRequest: URLRequest(url: WebUri(widget.url)),
                    initialUserScripts: UnmodifiableListView<UserScript>([]),
                    initialSettings: settings,
                    onWebViewCreated: (controller) {
                      webViewController = controller;
                      _inAppWebJSHandlerManager.updateController(
                        context: context,
                        inAppWebViewController: webViewController,
                      );
                      // 注入jsReady,前端覆盖了AppJSBridgeReady事件
                      //_inAppWebJSHandlerManager.injectJavascriptReady();
                      _inAppWebJSBridgeRegister.setContext(context);
                      _inAppWebJSBridgeRegister.registerHandlers();
                      String filePre = "file://";
                      if (widget.url.startsWith(filePre)) {
                        String html = widget.url.substring(filePre.length);
                        webViewController?.loadFile(
                            assetFilePath: 'assets/html/${html}');
                      } else {
                        if (widget.url.startsWith("http://") ||
                            widget.url.startsWith("https://")) {
                          webViewController?.loadUrl(
                              urlRequest: URLRequest(url: WebUri(widget.url)));
                        }
                      }

                      if (widget.onWebViewCreated != null) {
                        widget.onWebViewCreated!(controller);
                      }
                    },
                    onTitleChanged: (controller, title) {
                      if (widget.onWebTitleLoaded != null) {
                        widget.onWebTitleLoaded!(title);
                      }
                    },
                    onLoadStart: (controller, url) {},
                    onPermissionRequest: (controller, permissionRequest) async {
                      return PermissionResponse(
                          resources: permissionRequest.resources,
                          action: PermissionResponseAction.GRANT);
                    },
                    shouldOverrideUrlLoading: (controller, navigationAction) async {
                      var uri = navigationAction.request.url!;
                      bool canNavigate =
                      _inAppWebJSBridgeRegister.shouldOverrideUrlLoading(uri);
                      // 允许路由替换
                      return canNavigate
                          ? NavigationActionPolicy.ALLOW
                          : NavigationActionPolicy.CANCEL;
                    },
                    onLoadStop: (controller, url) async {
                      // 注入
                      _inAppWebJSHandlerManager.injectBridgeJavascript();

                      _inAppWebJSHandlerManager.checkJavascriptBridge();

                      // 加载完成
                      widget.onLoadFinished(url.toString());
                    },
                    onProgressChanged: (controller, progress) {
                      setState(() {
                        this.progress = progress / 100;
                      });
                      if (widget.onWebProgress != null) {
                        widget.onWebProgress!(progress);
                      }
                    },
                    onLoadError: (controller, Uri? url, int code, String message) {
                      if (widget.onWebResourceError != null) {
                        widget.onWebResourceError!(message);
                      }
                    },
                    onReceivedError: (controller, WebResourceRequest request,
                        WebResourceError error){
                      widget.onReceivedError!(error);
                    },
                    onUpdateVisitedHistory: (controller, url, androidIsReload) {
                      //LoggerManager().debug("onUpdateVisitedHistory：$url");
                    },
                    onConsoleMessage: (controller, consoleMessage) {
                      //LoggerManager().debug("consoleMessage：$consoleMessage");
                    },
                    onLoadResourceWithCustomScheme: (controller, resource) async {
                      if (resource.url.scheme =='base' ) {
                        File file = await FileUtil.getFileFromLocalStorage(resource
                            .url
                            .toString()
                            .replaceAll(AppConstant.schemePrefix, ""));
                        CustomSchemeResponse response = CustomSchemeResponse(
                          contentType: lookupMimeType(file.path)!,
                          data: file.readAsBytesSync(),
                        );
                        return response;
                      }
                    },
                  onReceivedServerTrustAuthRequest: (controller, challenge) async {
                    return ServerTrustAuthResponse(action: ServerTrustAuthResponseAction.PROCEED);
                  },

                ),
              ],
            )
        ),
      ],
    );
  }

}